<template>
  <!--   地图   -->
  <div class="map-box box-shadow">
    <div id="mapboxgl-box"/>
  </div>
  <div class="form-box box-shadow">
    <div class="set-header">
      <span>所选单元-{{cellInfo.cellName}}</span>
    </div>
    <div class="set-form">
      <span>标准设置</span>
      <a-form
          :model="tampNormFormState"
          :labelCol="{style: 'width: 140px'}"
          :wrapperCol="{span:24}"
          layout="inline">
        <a-form-item
            label="一遍点夯设计击数">
          <a-input-number v-model:value="tampNormFormState.timesPointFirst" :min="0"/>
        </a-form-item>
        <a-form-item
            label="二遍点夯设计击数">
          <a-input-number v-model:value="tampNormFormState.timesPointSecond" :min="0"/>
        </a-form-item>
        <a-form-item
            label="满夯设计击数">
          <a-input-number v-model:value="tampNormFormState.timesCover" :min="0"/>
        </a-form-item>
        <!--   换行    -->
        <a-form-item
            label="一遍点夯设计夯击能">
          <a-input-number v-model:value="tampNormFormState.energyPointFirst" :min="0" :step="0.1"/>
        </a-form-item>
        <a-form-item
            label="二遍点夯设计夯击能">
          <a-input-number v-model:value="tampNormFormState.energyPointSecond" :min="0" :step="0.1"/>
        </a-form-item>
        <a-form-item
            label="满夯设计夯击能">
          <a-input-number v-model:value="tampNormFormState.energyCover" :min="0" :step="0.1"/>
        </a-form-item>
        <a-form-item>
          <a-button @click="setTampNorm(cellInfo.cellId)" :disabled="cellInfo.cellId<0" type="primary">保存</a-button>
        </a-form-item>
      </a-form>
      <span>单元范围设置</span>
      <a-form
          :labelCol="{style: 'width: 140px'}"
          :wrapperCol="{span:24}"
          layout="inline">
        <a-form-item
            label="坐标系">
          <a-select
              v-model:value="coordinateType">
            <a-select-option
                v-for="coordinate in coordinateDict.dict"
                :key="coordinate.key" :value="coordinate.key">
              {{coordinate.value}}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item class="right-item">
          <a-button @click="openFileModal('uploadBorderFile')" :disabled="cellInfo.cellId<0" type="primary">导入
            <input
                id="uploadBorderFile"
                @change="readBorderFile(cellInfo.cellId)"
                accept=".txt"
                style="position:absolute;width:0;height:0;opacity:0"
                type="file"
            />
          </a-button>
          <a-button @click="getTampBorder(coordinateType,cellInfo.cellId,()=>{showBorderModal = true})" :disabled="cellInfo.cellId<0" type="primary">显示</a-button>
        </a-form-item>
      </a-form>
      <span>设计点设置</span>
      <a-form
          :model="tampDesignPointFormState"
          :labelCol="{style: 'width: 140px'}"
          :wrapperCol="{span:24}"
          layout="inline">
        <a-form-item
            label="点夯夯点间距">
          <a-input-number v-model:value="tampDesignPointFormState.tampDesignPoint" :min="0" :step="0.1"/>
        </a-form-item>
        <a-form-item class="right-item">
          <input
              id="uploadPointFile1"
              @change="readPointFile(cellInfo.cellId,1,'uploadPointFile1')"
              accept=".txt"
              style="position:absolute;width:0;height:0;opacity:0;"
              type="file"
          />
          <input
              id="uploadPointFile2"
              @change="readPointFile(cellInfo.cellId,2,'uploadPointFile2')"
              accept=".txt"
              style="position:absolute;width:0;height:0;opacity:0;"
              type="file"
          />
          <a-button @click="buildTampDesignPoint(cellInfo.cellId,1)" :disabled="cellInfo.cellId<0" type="primary">生成一遍夯点</a-button>
          <a-button @click="openFileModal('uploadPointFile1')" :disabled="cellInfo.cellId<0" type="primary">自定义设计点</a-button>
          <a-button @click="downloadPointFile(cellInfo.cellId,1)" :disabled="cellInfo.cellId<0" type="primary">下载设计点</a-button>
        </a-form-item>
        <a-form-item class="right-item">
          <a-button @click="buildTampDesignPoint(cellInfo.cellId,2)" :disabled="cellInfo.cellId<0" type="primary">生成二遍夯点</a-button>
          <a-button @click="openFileModal('uploadPointFile2')" :disabled="cellInfo.cellId<0" type="primary">自定义设计点</a-button>
          <a-button @click="downloadPointFile(cellInfo.cellId,2)" :disabled="cellInfo.cellId<0" type="primary">下载设计点</a-button>
        </a-form-item>
      </a-form>
    </div>
  </div>
  <SModal
      title="边界坐标"
      :width="372"
      :height="300"
      :isShow="showBorderModal"
      @closed="() => {showBorderModal = false}">
    <div class="add-modal-box">
      <a-table
          style="flex: 1"
          :data-source="tampBorder"
          :bordered="false"
          :scroll="{y: '180px' }"
          :pagination="false"
          :locale="{ emptyText: '暂无数据' }"
          :rowKey="(record) => record.lon">
        <a-table-column :title="coordinateType==1?'P坐标':'经度'" data-index="lon">
          <template #default="{text}">
            {{ text.toFixed(6) }}
          </template>
        </a-table-column>
        <a-table-column :title="coordinateType==1?'H坐标':'纬度'" data-index="lat">
          <template #default="{text}">
            {{ text.toFixed(6) }}
          </template>
        </a-table-column>
      </a-table>
    </div>
  </SModal>
</template>

<script lang="ts">
import {defineComponent, nextTick, onBeforeUnmount, onMounted, ref, watch} from "vue"
import coordinateDict from "@/dicts/coordinateDict"
import SModal from "@/components/SModal/index.vue"
import {tampCellInfo} from "@/hooks/cell/index"
import mapboxgl,{AnyLayer,Sources} from "mapbox-gl"
import redLine from "@/assets/data/redLine"
import "mapbox-gl/dist/mapbox-gl.css"
import {message} from "ant-design-vue"
import KindEnum from "@/enums/kindEnum"
import config from "@/config/index"
import axios from "@/utils/axios";
import qs from "qs";

interface MapLayerRequestInfo{
  craft:string|null
  cellId:number|null
  type:string|null
}

export default defineComponent({
  setup(props){
    const coordinateType = ref(1)
    const showBorderModal = ref(false)
    const {
      tampNormFormRef,
      tampNormFormState,
      tampNormRules,
      tampNorm,
      tampCoordinateTypeFormRef,
      tampCoordinateTypeFormState,
      tampCoordinateTypeFormRules,
      tampBorder,

      tampDesignPointFormRef,
      tampDesignPointFormState,
      tampDesignPointFormRules,
      tampDesignPoint,

      getTampNorm,
      setTampNorm,
      getTampBorder,
      setTampBorder,
      buildTampDesignPoint,
      setTampDesignPoint,
      createTiledMap
    } = tampCellInfo()

    // 打开input[file]窗口
    const openFileModal = (id:string)=>{
      document.getElementById(id)?.click();
    }

    // 读取边界数据
    const readBorderFile = (cellId:number)=>{
      let inputDOM: any = document.getElementById("uploadBorderFile")
      let files = inputDOM.files

      if (files[0]) {
        let reader = new FileReader();
        reader.readAsText(files[0], "UTF-8");
        reader.onload = (e: any)=>{
          try{
            let fileStr = e.target.result;
            let fileStrArr = fileStr.split(",,")
            tampCoordinateTypeFormState.value.cellId = cellId
            tampCoordinateTypeFormState.value.count = 0
            tampCoordinateTypeFormState.value.first = new Array()
            tampCoordinateTypeFormState.value.second = new Array()

            for (let i = 0; i < fileStrArr.length; i++) {
              let pointArr = fileStrArr[i].split(",")
              if (pointArr.length == 2) {
                tampCoordinateTypeFormState.value.count++
                tampCoordinateTypeFormState.value.first.push(parseFloat(pointArr[0]))
                tampCoordinateTypeFormState.value.second.push(parseFloat(pointArr[1]))
              }
            }
            setTampBorder(coordinateType.value,(res:any)=>{
              if(res.data.count>=3){
                let minX = res.data.second[0]
                let maxX = res.data.second[0]
                let minY = res.data.first[0]
                let maxY = res.data.first[0]
                for (let i= 0; i< res.data.count; i++){
                  minX = minX > res.data.second[i] ? res.data.second[i] : minX
                  maxX = maxX < res.data.second[i] ? res.data.second[i] : maxX
                  minY = minY > res.data.first[i] ? res.data.first[i] : minY
                  maxY = maxY < res.data.first[i] ? res.data.first[i] : maxY
                }
                if(maps.map) {
                  maps.map.setZoom(16)
                  maps.map.jumpTo({center: new mapboxgl.LngLat((minY+maxY)/2, (minX+maxX)/2)})
                }
              }
            })
          }catch (e){
            message.warn("导入格式错误")
          }
        }
        inputDOM.value = "";
      }
    }

    // 读取设计点数据
    const readPointFile = (cellId:number, type:number, input:string)=>{
      let inputDOM: any = document.getElementById(input)
      let files = inputDOM.files

      if (files[0]) {
        let reader = new FileReader();
        reader.readAsText(files[0], "UTF-8");
        reader.onload = (e: any)=>{
          let fileStr = e.target.result
          let fileStrArr = fileStr.split(",,")

          let data = {
            cellId:cellId,
            count:0,
            kind:type,
            first:new Array<number>(),
            second:new Array<number>(),
            pointName: new Array<string>()
          }

          for (let i = 0; i < fileStrArr.length; i++) {
            let pointArr = fileStrArr[i].split(",")
            if (pointArr.length == 3) {
              data.count++

              let name = String(pointArr[0]).trim()
              let nameLength = name.length
              if(nameLength==0||nameLength>10){
                message.info("点位长度过短或过长")
                return
              }
              data.pointName.push(name)
              data.first.push(parseFloat(pointArr[1]))
              data.second.push(parseFloat(pointArr[2]))
            }
          }
          setTampDesignPoint(data)
          createTiledMap(cellId,1).then((res2:any)=>{
            axios.post("/qhMap/reCreatReport",
                qs.stringify({
                  cellID:cellId,
                  workType:1,
                }),{
                  headers: {'Content-Type': 'application/x-www-form-urlencoded'}
                })
            axios.post("/qhMap/reCreatReport",
                qs.stringify({
                  cellID:cellId,
                  workType:2,
                }),{
                  headers: {'Content-Type': 'application/x-www-form-urlencoded'}
                })
            axios.post("/qhMap/reCreatReport",
                qs.stringify({
                  cellID:cellId,
                  workType:11,
                }),{
                  headers: {'Content-Type': 'application/x-www-form-urlencoded'}
                })
          })
        }
        inputDOM.value = "";
      }
    }



    // 下载设计点数据
    const downloadPointFile = (cellId:number, kind:number)=>{
      axios.post(
          "/tamp/downloadDesignPoint",
      {cellId: cellId, kind: kind},
      {
        responseType: 'blob'
      })
      .then((res:any)=>{
        // 前端获取业务码，成功执行正常业务
        const link = document.createElement('a');
        link.target = "_blank";
        link.href = URL.createObjectURL(res); // 创建下载的链接
        link.download = `${props.cellInfo.cellName}.xlsx`; // 下载后文件名
        link.click(); // 点击下载
        URL.revokeObjectURL(link.href); // 释放掉blob对象
        document.body.removeChild(link); // 下载完成移除元素
      })
    }

    let maps:any
    // 初始化地图
    const initMap = ()=>{
      mapboxgl.accessToken = config.map.accessToken
      let mapSource:Sources = {
        google: {
          type: "raster",
          tiles: [config.map.baseLayer1URL,config.map.baseLayer2URL,config.map.baseLayer3URL],
          tileSize: 256,
        },
      }
      let layers:AnyLayer[] = [
        {
          id: "google-tiles1",
          type: "raster",
          source: "google",
        },
      ]
      maps = {
        map:new mapboxgl.Map({
          container: "mapboxgl-box",
          style: {
            version: 8,
            sources: mapSource,
            layers: layers,
          },
          minZoom: 5,
          center: config.map.center,
          zoom: 13,
          attributionControl: false
        }),
        sourceList: new Set<string>(),
        LayerList: new Set<string>()
      }

      maps.map.on("load",()=>{
        maps.map.addLayer({
          id: "air",
          type: "raster",
          source: {
            type: "raster",
            tiles: [config.map.airUrl],
          },
        })
        maps.map.addSource("readLineSource",{type:"geojson",data:redLine})
        maps.map.addLayer({
          id: "readLineLayer",
          type: "line",
          source: "readLineSource",
          layout: {},
          paint: {
            "line-color":"#ff0000",
            "line-width":2,
            "line-opacity":1
          },
        })
      })
    }

    // 添加边界图层
    const addBorderLayer = (id:number)=>{
      if(!maps.map) return
      let layerInfo:MapLayerRequestInfo = {
        cellId:id,
        craft:"HaErBin-QH",
        type:"border"
      }
      if(maps.map.getLayer(`${layerInfo.type}`)) maps.map.removeLayer(`${layerInfo.type}`)
      if(maps.map.getSource(`${layerInfo.type}`)) maps.map.removeSource(`${layerInfo.type}`)

      maps.map.addSource(`${layerInfo.type}`,{
        type: "raster",
        scheme:"tms",
        tiles: [
          `${config.map.geoServer}${layerInfo.craft}%3A${layerInfo.cellId}_${layerInfo.type}@EPSG%3A900913@png/{z}/{x}/{y}.png`
        ],
        tileSize: 256,
      })
      maps.map.addLayer({
        id: `${layerInfo.type}`,
        type: "raster",
        source: `${layerInfo.type}`,
        paint: {
          "raster-opacity": 1,
        },
      })
    }

    watch(()=>props.cellInfo,(newValue,oldValue)=>{
      setTimeout(()=>{
        if(!newValue||newValue.cellId<=0) return
        if(newValue.kind!=KindEnum.tamp) return
        getTampNorm(newValue.cellId)
        addBorderLayer(newValue.cellId)
        getTampBorder(2,newValue.cellId,(res:any)=>{
          if(res.data.borderCount>=3){
            let minX = res.data.second[0]
            let maxX = res.data.second[0]
            let minY = res.data.first[0]
            let maxY = res.data.first[0]
            for (let i= 0; i< res.data.borderCount; i++){
              minX = minX > res.data.second[i] ? res.data.second[i] : minX
              maxX = maxX < res.data.second[i] ? res.data.second[i] : maxX
              minY = minY > res.data.first[i] ? res.data.first[i] : minY
              maxY = maxY < res.data.first[i] ? res.data.first[i] : maxY
            }
            if(maps.map) {
              maps.map.setZoom(16)
              maps.map.jumpTo({center: new mapboxgl.LngLat((minY+maxY)/2, (minX+maxX)/2)})
            }
          }
        })
      },500)
    },{immediate: true})

    onMounted(()=>{
      initMap()
    })

    onBeforeUnmount(()=>{
      maps.map.remove()
    })

    return {
      coordinateType,
      coordinateDict,
      openFileModal,
      readBorderFile,
      readPointFile,
      showBorderModal,

      tampNormFormRef,
      tampNormFormState,
      tampNormRules,
      tampNorm,

      tampCoordinateTypeFormRef,
      tampCoordinateTypeFormState,
      tampCoordinateTypeFormRules,
      tampBorder,

      tampDesignPointFormRef,
      tampDesignPointFormState,
      tampDesignPointFormRules,
      tampDesignPoint,

      getTampNorm,
      setTampNorm,
      getTampBorder,
      setTampBorder,
      buildTampDesignPoint,
      downloadPointFile
    }
  },
  props: {
    isShow: {
      type: Boolean,
      default: false
    },
    cellInfo: {
      type: Object,
      default: null
    }
  },
  components:{SModal}
})
</script>

<style lang="scss" scoped>
.map-box{
  position: relative;
  flex: 1;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  #mapboxgl-box{
    display: flex;
    width: 100%;
    height: calc(100% - 6px);
    box-sizing: border-box;
  }
}
.form-box{
  display: flex;
  flex-direction: column;
  margin-top: 20px;
  width: 100%;
  height: 450px;
  padding: 18px 30px 10px 30px;
  box-sizing: border-box;
  .set-header{
    font-size: 18px;
    font-weight: bold;
    color: #333333;
    padding-bottom: 10px;
    border-bottom: 1px solid #EDF0FB;
  }
  .set-form{
    flex: 1;
    width: 100%;
    >span{
      display: block;
      padding: 12px 0px 5px;
      font-size: 16px;
      font-weight: bold;
      color: #333333;
    }
    ::v-deep .ant-select{
      width: 177px;
    }
    ::v-deep .ant-input-number{
      width: 177px;
    }
    ::v-deep label{
      color: #666666;
    }
    .right-item{
      float: right;
      ::v-deep button{
        margin-left: 18px;
      }
    }
  }
}
</style>
